﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Kinect;

namespace KinectPowerPointControl_sample1_Fukidashi
{

    enum HandHeight
    {
        High, Normal, Low, Lowest
    }

    static class ProcessForwardBackGesture
    {
        static bool isForwardGestureActive = false;
        static bool isBackGestureActive = false;

        static Joint head;
        static Joint rightHand;
        static Joint leftHand;
        static Joint spine;

        static double diffPositionX = 0.5;
        static double diffPositionY = 0.2;

        static long lastActivated = 0; //最後にこのジェスチャーが発生したタイミング（100ナノ秒単位のtickで保持）
        static long SLEEP_TIME = 10 * 1000 * 1000 * 10; //発動後、発動を抑える時間

        public static bool nextState(JointCollectionEquivalent joints)
        {

            if (getSkeleton(joints))
            {
                return false;
            }

            if (rightHand.Position.X > head.Position.X + diffPositionX)
            {
                if (!isBackGestureActive && !isForwardGestureActive)
                {
                    isForwardGestureActive = true;
                    //System.Windows.Forms.SendKeys.SendWait("{Right}");
                    return true;
                }
            }
            else
            {
                isForwardGestureActive = false;
            }
            return false;

        }

        public static bool backState(JointCollectionEquivalent joints)
        {
            if (getSkeleton(joints))
            {
                return false;
            }

            if (leftHand.Position.X < head.Position.X - diffPositionX)
            {
                if (!isBackGestureActive && !isForwardGestureActive)
                {
                    isBackGestureActive = true;
                    return true;
                }
            }
            else
            {
                isBackGestureActive = false;
            }
            return false;
        }

        public static HandHeight handHeightState(JointCollectionEquivalent joints, bool isRight){
            if( isRight){
                //　右手判定か
                if (rightHand.Position.Y > head.Position.Y)
                {
                    return HandHeight.High;
                }
                else if (rightHand.Position.Y > head.Position.Y - diffPositionY)
                {
                    return HandHeight.Normal;
                }
                else if (rightHand.Position.Y > head.Position.Y - diffPositionY * 2)
                {
                    return HandHeight.Low;
                }
                else
                {
                    return HandHeight.Lowest;
                }
            }else{
                //　右手判定か
                if (leftHand.Position.Y > head.Position.Y)
                {
                    return HandHeight.High;
                }
                else if (leftHand.Position.Y > head.Position.Y - diffPositionY)
                {
                    return HandHeight.Normal;
                }
                else if (leftHand.Position.Y > head.Position.Y - diffPositionY * 2)
                {
                    return HandHeight.Low;
                }
                else
                {
                    return HandHeight.Lowest;
                }
            }
        }


        private static bool getSkeleton(JointCollectionEquivalent joints)
        {

            head = joints[JointType.Head];
            rightHand = joints[JointType.HandRight];
            leftHand = joints[JointType.HandLeft];
            spine = joints[JointType.Spine];

            if (head.TrackingState != JointTrackingState.Tracked ||
                rightHand.TrackingState != JointTrackingState.Tracked ||
                leftHand.TrackingState != JointTrackingState.Tracked ||
                spine.TrackingState != JointTrackingState.Tracked)
            {
                //Don't have a good read on the joints so we cannot process gestures
                return true;
            }
            return false;
        }



        private static int judgeTime = 10;

        public static bool hasNextState(LinkedList<SkeletonLog> skeletonLogs)
        {

            if ( DateTime.Now.Ticks - lastActivated > SLEEP_TIME) { lastActivated = 0; } //発動後、発動を抑える時間が経過した場合
            if (skeletonLogs.Count <= judgeTime ||   //直近3秒の断面が存在しない場合
                lastActivated > 0)          //発動後、発動を抑える時間が経過した場合
            {
                return false;
            }

            LinkedList<SkeletonLog>.Enumerator e = skeletonLogs.GetEnumerator();

            //以下を満たすか
            //ここ3秒の間、ずっと右手が右側にある

            for (int i = 0; i < judgeTime; i++)
            {
                if (!e.MoveNext()) { return false; }
                if (e.Current.joints[JointType.HandRight].Position.X < e.Current.joints[JointType.Head].Position.X + diffPositionX)
                {
                    return false;
                }
            }

            lastActivated = DateTime.Now.Ticks;
            return true;
        }

    }

}
